package org.raymond.iworks.study.basic.thread.forkjoinpool;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.RecursiveTask;

@Slf4j
public class Demo1 {
    public static void main(String[] args) {
        test1();
    }
    public static void test1(){
        // parallelism表示并行级别,表示任务所需的线程或CPU数量,如果是默认构造会自动识别当前电脑的cup核数进行并行
        ForkJoinPool forkJoinPool = new ForkJoinPool(4);
        WorkLoadAction action = new WorkLoadAction(24l);
        forkJoinPool.invoke(action);

        WorkLoadTask task = new WorkLoadTask(24l);
        //long result = forkJoinPool.invoke(task);
        //log.info("最终结果:{}", result);
    }

    static class WorkLoadAction extends RecursiveAction {
        private long workload;

        public WorkLoadAction(Long workload){
            this.workload = workload;
        }

        @Override
        protected void compute() {
            //如果工作超出阈值,将任务分解成更小的任务
            if(workload>10){
                // 将工作负载分成多个子任务
                log.info("将工作负载 {}", workload);
                List<WorkLoadAction> subActions = createSubAction();
                // 将子任务加入到任务队列中
                for(WorkLoadAction action : subActions){
                    action.fork();
                }
            }else{
                log.info("自己完成的工作量:{}", this.workload);
            }
        }

        private List<WorkLoadAction> createSubAction(){
            List<WorkLoadAction> subActions = new ArrayList<>();
            //将工作负载分成两个子任务
            WorkLoadAction subtask1 = new WorkLoadAction(this.workload / 2);
            WorkLoadAction subtask2 = new WorkLoadAction(this.workload / 2);
            subActions.add(subtask1);
            subActions.add(subtask2);
            return subActions;
        }
    }

    static class WorkLoadTask extends RecursiveTask<Long> {
        private long workload;
        public WorkLoadTask(long workload){
            this.workload = workload;
        }

        @Override
        protected Long compute() {
            if(workload>10){
                // 将工作负载分成多个子任务
                log.info("将工作负载 {}", workload);
                List<WorkLoadTask> subTasks = createSubTask();
                // 将子任务加入到任务队列中
                for(WorkLoadTask task : subTasks){
                    task.fork();
                }
                //等待子任务执行完，并得到其结果,并将结果相加
                long result = 0;
                for(WorkLoadTask subtask : subTasks) {
                    result += subtask.join();
                }
                return result;
            }else{
                log.info("自己完成工作量: " + this.workload);
                return 1L ;//返回计算结果
            }
        }

        private List<WorkLoadTask> createSubTask(){
            List<WorkLoadTask> subTasks = new ArrayList<>();
            //将工作负载分成两个子任务
            WorkLoadTask subtask1 = new WorkLoadTask(this.workload / 2);
            WorkLoadTask subtask2 = new WorkLoadTask(this.workload / 2);
            subTasks.add(subtask1);
            subTasks.add(subtask2);
            return subTasks;
        }
    }
}
